package com.itheima.stock.stocktimertesk.impl;

import com.google.common.collect.Lists;
import com.itheima.stock.config.StockInfoConfig;
import com.itheima.stock.face.impl.StockCacheFaceImpl;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockOuterMarketIndexInfoMapper;
import com.itheima.stock.pojo.StockBlockRtInfo;
import com.itheima.stock.stocktimertesk.StockTimerTaskService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.utils.ParserStockInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: siwukun
 * @date: 2022/06/05
 * @description:
 */
@Service
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    //数据拉取模板
    @Autowired
    private RestTemplate restTemplate;
    //注入大盘、板块url
    @Autowired
    private StockInfoConfig stockInfoConfig;
    //注入生成全球唯一id生成器
    @Autowired
    private IdWorker idWorker;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    //注入解析工具类
    @Autowired
    private ParserStockInfoUtil parserStockInfoUtil;

    //注入线程池
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private StockOuterMarketIndexInfoMapper stockOuterMarketIndexInfoMapper;

    @Autowired
    private StockCacheFaceImpl stockCacheFace;
    @Override
    public void pullInnerStockData() {
        //定义url
        String url = stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getInner());
        //因为是拉取新浪网的信息，这是要设置请求头 Referer，user-agent
        String referer ="https://finance.sina.com.cn/stock/";
        String userAgent ="User-Agent\",\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36";
        //创建HttpHeader对象
        HttpHeaders headers = new HttpHeaders();//等同于map集合
        //Referer，user-agent
        headers.add("Referer",referer);
        headers.add("User-Agent",userAgent);
        //组装请求对象
        HttpEntity<HttpHeaders> httpHeadersHttpEntity = new HttpEntity<>(headers);
        // resetTemplate发起post请求
        //forObject 请求得到的json字符串
        String forObject = restTemplate.postForObject(url, httpHeadersHttpEntity, String.class);
        //添加数据到数据库
        //1代表国内大盘
        List infos = parserStockInfoUtil.parser4StockOrMarketInfo(forObject, 1);
        stockMarketIndexInfoMapper.insertInnerStockData(infos);
        log.info("list=",infos);
    }

    /**
     * 个股实时数据批量保存
     */
    @Override
    public void pullStockRtIndex() {
//        //获取所有的股票code
//        List<String> codes = stockBusinessMapper.getAllByCode();
//        //根据code吗区分是sh还是sz
//        List<String> addPrefixCodes =  codes.stream().map(code -> {
//           return code = code.startsWith("6") ? "sh" + code : "sz" + code;
//        }).collect(Collectors.toList());
        //缓存处理
        List<String> rtIndex = stockCacheFace.getAShareStockCodes();
        //如果所所得数据一次性插入造成很大的i/o开销，所以个考虑借助分片处理
        List<List<String>> listList = Lists.partition(rtIndex, 10);
        //因为是拉取新浪网的信息，这是要设置请求头 Referer，user-agent
        String referer ="https://finance.sina.com.cn/stock/";
        String userAgent ="User-Agent\",\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36";
        //创建HttpHeader对象
        HttpHeaders headers = new HttpHeaders();//等同于map集合
        //Referer，user-agent
        headers.add("Referer",referer);
        headers.add("User-Agent",userAgent);
        //组装请求对象
        HttpEntity<HttpHeaders> httpHeadersHttpEntity = new HttpEntity<>(headers);
        listList.stream().forEach(list->{
            //创建线程池提交任务
            threadPoolTaskExecutor.execute(()->{
            //获取请求url
            //定义url
            String url = stockInfoConfig.getMarketUrl()+String.join(",",list);
            String forObject = restTemplate.postForObject(url, httpHeadersHttpEntity, String.class);
            List infos = parserStockInfoUtil.parser4StockOrMarketInfo(forObject, 3);
            stockMarketIndexInfoMapper.insertInnerStockIndexData(infos);
        });
        });
    }

    /**
     * 获取板块数据
     */
    @Override
    public void getStockSectorRtIndex() {
        //获取url  http://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php
        //不需要设置请求头
        String url = "http://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php";
        //使用restTemplate获取请求数据
        String getData = restTemplate.getForObject(url, String.class);
        String[] split = getData.split("=");
        String[] split1 = split[1].split(":");
        List<StockBlockRtInfo> infos = new ArrayList<>();
        for (int i = 1; i < split1.length; i++) {
            String[] data = split1[i].split(",");
            //["new_blhy, 玻璃行业, 19, 14.177894736842, -0.0015789473684211, -0.01113544411863, 303361029, 3433488809, sh603601, 4.013, 6.220, 0.240, 再升科技", "new_cbzz"]
            if (data==null){
                return;
            }
            //去掉"
            data[0] = data[0].substring(1);
            //获取当前时间
            Date now=DateTimeUtil.getDateTimeWithoutSecond(DateTime.now()).toDate();
            //组装数据
            StockBlockRtInfo info = StockBlockRtInfo.builder().id(idWorker.nextId() + "")
                    .label(data[0])
                    .blockName(data[1])
                    .companyNum(Integer.parseInt(data[2]))
                    .avgPrice(new BigDecimal(data[3]))
                    .tradeAmount(Long.valueOf(data[6]))
                    .updownRate(new BigDecimal(data[4]))
                    .tradeVolume(new BigDecimal(data[7]))
                    .curTime(now)
                    .build();
            infos.add(info);
        }
        //分片插入
        Lists.partition(infos,10).stream().forEach(list->{
            //创建线程池提交任务
            threadPoolTaskExecutor.submit(()->{
                    //保存板块数据
            int count = stockBlockRtInfoMapper.insertStockSectorRtIndex(infos);
            System.out.println(count);
            });
        });
    }

    /**
     * 拉取外盘数据功能实现
     */
    @Override
    public void StockOutMarketData() {
        //定义url
        String url = stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getOuter());
        //因为是拉取新浪网的信息，这是要设置请求头 Referer，user-agent
        String referer ="https://finance.sina.com.cn/stock/";
        String userAgent ="User-Agent\",\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36";
        //创建HttpHeader对象
        HttpHeaders headers = new HttpHeaders();//等同于map集合
        //Referer，user-agent
        headers.add("Referer",referer);
        headers.add("User-Agent",userAgent);
        //组装请求对象
        HttpEntity<HttpHeaders> httpHeadersHttpEntity = new HttpEntity<>(headers);
        // resetTemplate发起post请求
        //forObject 请求得到的json字符串
        String forObject = restTemplate.postForObject(url, httpHeadersHttpEntity, String.class);
        List infos = parserStockInfoUtil.parser4StockOrMarketInfo(forObject, 2);
        int count = stockOuterMarketIndexInfoMapper.insertInnerStockOutData(infos);
        log.info("list=",infos,count);

    }

    /**
     *   //获取所有的股票code
     *         List<String> codes = stockBusinessMapper.getAllByCode();
     *         //根据code吗区分是sh还是sz
     *         List<String> addPrefixCodes =  codes.stream().map(code -> {
     *            return code = code.startsWith("6") ? "sh" + code : "sz" + code;
     *         }).collect(Collectors.toList());
     */

    public List<String> getStockRtIndex(){
     List<String> codes = stockBusinessMapper.getAllByCode();
            //根据code吗区分是sh还是sz
        List<String> addPrefixCodes =  codes.stream().map(code -> {
            return code = code.startsWith("6") ? "sh" + code : "sz" + code;
            }).collect(Collectors.toList());
        return addPrefixCodes;
    }

}
